from django import template
from django import forms
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
import datetime
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from pirate_core import HttpRedirectException, namespace_get, FormMixin
from pirate_issues.models import Topic, Issue
from pirate_consensus.models import UpDownVote, Consensus
from django.utils.translation import ugettext as _
from pirate_reputation.models import ReputationDimension
from django.contrib.auth import authenticate, login
from django.core.validators import validate_email
from pirate_core.views import template_for_model

from pirate_signals.models import aso_rep_event
from pirate_login.models import Login, Register

from customtags.decorators import block_decorator
register = template.Library()
block = block_decorator(register)

'''
This file contains all of the tags that pertain to User/Login objects
'''


# this function assignment lets us reuse the same code block a bunch of places
get_namespace = namespace_get('pp_login')


@block    
def pp_user_registration_form(context, nodelist, *args, **kwargs):
    '''form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_user_registration_form")
    This block tag can create or process forms either to create or to modify issues.
    Usage is as follows:

    {% pp_user_registration_form request=request return_path=request.MATH.PATH_INFO return_query=request.META.QUERY_STRING %}
       Do stuff with {{ pp_login.form }}.
    {% endpp_user_login_form%}
    '''
    context.push()
    namespace = get_namespace(context)

    request = kwargs.get('request')
    return_path= kwargs.get('return_path')
    return_query= kwargs.get('return_query')
    returnurl = kwargs.get('returnurl') #this is for register.html
    
    if request is not None: 
        POST = request.POST
    else:
        raise ValueError("Tag pp_user_login_form must contain the argument 'request=request'")
    
    if return_path is not None and return_query is not None:
        returnurl = return_path + '?' + return_query
    elif returnurl is not None:
        returnurl = returnurl.replace('%','&')
    else:
        returnurl = '/issues.html?_s=0&_e=20&_d=hot'

    if POST and POST.get("form_id") == "pp_user_registration_form":
        try:        
            form = RegisterForm(POST) 
            if form.is_valid():
                new_user = form.save()      
                if new_user.password1 ==  new_user.password2: 
                    #check to see if there are other users with this name
                    try:
                        ui = User.objects.get(username=new_user.name)
                        namespace['errors'] = "Sorry that username is taken already, please pick another."
                    except:
                        user = User.objects.create_user(new_user.name, new_user.email, new_user.password1)   
                        user = authenticate(username=new_user.name, password=new_user.password1)
                        if user is not None:    
                            if user.is_active:
                                login(request, user)
                        raise HttpRedirectException(HttpResponseRedirect(returnurl))
                else:
                    namespace['errors'] = "Passwords are not the same. Try again."

        except HttpRedirectException, e:
            raise e
    else:
        form = RegisterForm()

    namespace['form'] = form
    output = nodelist.render(context)
    context.pop()    

    return output


class RegisterForm(forms.ModelForm):
    def save(self, commit=True):
        new_user = super(RegisterForm, self).save(commit=False)
        return new_user

    class Meta:
        model = Register
    
    form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_user_registration_form")
    password1 = forms.CharField(label=_(u'Password'),widget=forms.PasswordInput(render_value=False))
    password2 = forms.CharField(label=_(u'Password Check'),widget=forms.PasswordInput(render_value=False))
    email = forms.CharField(label=_(u'Email'),validators = [validate_email])



@block    
def pp_user_login_form(context, nodelist, *args, **kwargs):
    '''form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_user_login_form")
    This block tag can create or process forms either to create or to modify issues.
    Usage is as follows:

    {% pp_user_login_form request=request return_path=request.MATH.PATH_INFO return_query=request.META.QUERY_STRING %}
       Do stuff with {{ pp_login.form }}.
    {% endpp_user_login_form%}
    '''
    context.push()
    namespace = get_namespace(context)

    request = kwargs.get('request')
    return_path= kwargs.get('return_path')
    return_query= kwargs.get('return_query')
    returnurl = kwargs.get('returnurl') #this is for register.html
    
    if request is not None:
        POST = request.POST
    else:
        raise ValueError("Tag pp_user_login_form must contain the argument 'request=request'")
    if return_path is not None and return_query is not None:
        returnurl = return_path + '?' + return_query
    elif returnurl is not None:
        returnurl = returnurl.replace('%','&')
    elif return_path is not None and return_query is None:
        returnurl = return_path
    else:
        returnurl = '/issues.html?_s=0&_e=20&_d=hot'

    if POST and POST.get("form_id") == "pp_user_login_form":
        try:                   
            form = LoginForm(POST)
            if form.is_valid():
                new_user = form.save()    
                user = authenticate(username=new_user.name, password=new_user.password)
                if user is not None:
                    if user.is_active:
                        login(request, user)
                else: #TODO: form is erroneous somehow, need to find out how and add to error text
                    pass

                raise HttpRedirectException(HttpResponseRedirect(returnurl))
            else: #TODO: form is empty in some way, add this message to error
                pass
            
        except HttpRedirectException, e:
            raise e
    else:
        form = LoginForm()

    namespace['form'] = form
    output = nodelist.render(context)
    context.pop()    

    return output



class LoginForm(forms.ModelForm):
    
    def save(self, commit=True):
        new_user = super(LoginForm, self).save(commit=False)
        return new_user

    class Meta:
        model = Login 
    form_id = forms.CharField(widget=forms.HiddenInput(), initial="pp_user_login_form")
    name = forms.CharField(label=_(u'Name'))
    password = forms.CharField(label=_(u'Pass'),widget=forms.PasswordInput(render_value=False))
